<!-- src/components/FileUpload.vue -->
<template>
  <div class="file-upload">
    <div
        class="upload-area"
        @click="triggerFileInput"
        @dragover="handleDragOver"
        @drop="handleDrop"
    >
      <input
          ref="fileInput"
          multiple
          style="display: none"
          type="file"
          @change="handleFileSelect"
      />
      <div class="upload-content">
        <div class="upload-icon">📁</div>
        <p>点击或拖拽文件到此处上传</p>
        <small>支持大文件分片上传和断点续传</small>
      </div>
    </div>

    <div class="file-list">
      <div
          v-for="file in files"
          :key="file.id"
          class="file-item"
      >
        <div class="file-info">
          <div class="file-name">{{ file.name }}</div>
          <div class="file-meta">
            <span class="file-size">{{ formatFileSize(file.size) }}</span>
            <span :class="`status-${file.status}`" class="file-status-text">
              {{ getStatusText(file) }}
            </span>
          </div>
        </div>

        <div class="upload-progress">
          <div class="progress-bar">
            <div
                :class="{ 'progress-success': file.status === 'success' }"
                :style="{ width: file.progress + '%' }"
                class="progress-fill"
            ></div>
          </div>
          <div class="progress-text">{{ file.progress }}%</div>
        </div>

        <div class="file-actions">
          <button
              v-if="file.status === 'error' || file.status === 'pending'"
              class="retry-btn"
              @click="retryUpload(file)"
          >
            重试
          </button>
          <button
              v-if="file.status === 'uploading'"
              class="cancel-btn"
              @click="cancelUpload(file)"
          >
            取消
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import {ref} from 'vue';
import {FileUploader} from './ts/BigFileUpload';
import {currentBucketName, currentPath, formatFileSize} from "@/views/documentManager/components/ts/FileBrowser";

interface UploadFile {
  id: string;
  file: File;
  name: string;
  size: number;
  progress: number;
  status: 'pending' | 'uploading' | 'success' | 'error';
  uploader?: FileUploader;
  url?: string;
  errorMessage?: string;
}

const files = ref<UploadFile[]>([]);
const fileInput = ref<HTMLInputElement>();

// 定义事件
const emit = defineEmits(['uploadSuccess', 'uploadError']);


const triggerFileInput = () => {
  fileInput.value?.click();
};

const handleFileSelect = (event: Event) => {
  const target = event.target as HTMLInputElement;
  if (target.files) {
    handleFiles(Array.from(target.files));
    // 清空input，允许重复选择相同文件
    target.value = '';
  }
};

const handleDrop = (event: DragEvent) => {
  event.preventDefault();
  if (event.dataTransfer?.files) {
    handleFiles(Array.from(event.dataTransfer.files));
  }
};

const handleDragOver = (event: DragEvent) => {
  event.preventDefault();
};

const handleFiles = (fileList: File[]) => {
  fileList.forEach(file => {
    const uploadFile: UploadFile = {
      id: generateId(),
      file,
      name: file.name,
      size: file.size,
      progress: 0,
      status: 'pending'
    };

    files.value.push(uploadFile);
    startUpload(uploadFile);
  });
};

// 在 Vue 组件中修改 startUpload 方法
const startUpload = (uploadFile: UploadFile) => {
  uploadFile.status = 'uploading';
  console.log(`开始上传文件: ${uploadFile.name}`);

  const uploader = new FileUploader(
      uploadFile.file,
      currentBucketName.value,
      currentPath.value,
      (progress) => {
        console.log(`文件 ${uploadFile.name} 进度更新:`, progress.percentage + '%');
        // 强制更新：创建一个新对象来触发响应式更新
        uploadFile.progress = progress.percentage;

        // 强制触发 Vue 的响应式更新
        files.value = [...files.value];
      },
      (mergeRes: any) => {
        uploadFile.status = 'success';
        uploadFile.progress = 100;
        uploadFile.url = mergeRes.url;
        // 成功时也强制更新
        files.value = [...files.value];

        emit('uploadSuccess', uploadFile.name);
      },
      (error) => {
        uploadFile.status = 'error';
        uploadFile.errorMessage = error;
        // 错误时也强制更新
        files.value = [...files.value];
        console.error(`文件 ${uploadFile.name} 上传失败:`, error);
      }
  );

  uploadFile.uploader = uploader;
  uploader.startUpload();
};

const retryUpload = (uploadFile: UploadFile) => {
  console.log(`重试上传文件: ${uploadFile.name}`);
  uploadFile.progress = 0;
  uploadFile.status = 'pending';
  uploadFile.errorMessage = undefined;
  startUpload(uploadFile);
};

const cancelUpload = (uploadFile: UploadFile) => {
  console.log(`取消上传文件: ${uploadFile.name}`);
  if (uploadFile.uploader) {
    uploadFile.uploader.cancelUpload();
  }
  uploadFile.status = 'error';
  uploadFile.errorMessage = '上传已取消';
};

const getStatusText = (file: UploadFile): string => {
  switch (file.status) {
    case 'uploading':
      return '上传中';
    case 'success':
      return '上传成功';
    case 'error':
      return file.errorMessage || '上传失败';
    default:
      return '等待上传';
  }
};


const generateId = (): string => {
  return Date.now().toString(36) + Math.random().toString(36).substr(2);
};
</script>

<style scoped>
.file-upload {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
}

.upload-area {
  border: 2px dashed #dcdfe6;
  border-radius: 8px;
  padding: 40px;
  text-align: center;
  cursor: pointer;
  transition: all 0.3s;
  margin-bottom: 20px;
  background: #fafafa;
}

.upload-area:hover {
  border-color: #409eff;
  background: #f0f7ff;
}

.upload-content {
  color: #606266;
}

.upload-icon {
  font-size: 48px;
  margin-bottom: 16px;
}

.file-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.file-item {
  display: flex;
  align-items: center;
  padding: 16px;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  background: white;
  transition: all 0.3s;
}

.file-item:hover {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.file-info {
  flex: 1;
  min-width: 0;
}

.file-name {
  font-weight: 500;
  margin-bottom: 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-meta {
  display: flex;
  gap: 12px;
  font-size: 12px;
  color: #909399;
}

.upload-progress {
  flex: 2;
  display: flex;
  align-items: center;
  margin: 0 20px;
  min-width: 200px;
}

.progress-bar {
  flex: 1;
  height: 8px;
  background: #ebeef5;
  border-radius: 4px;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  background: #409eff;
  transition: width 0.3s;
}

.progress-fill.progress-success {
  background: #67c23a;
}

.progress-text {
  width: 60px;
  text-align: right;
  font-size: 12px;
  color: #606266;
  margin-left: 12px;
}

.file-actions {
  display: flex;
  gap: 8px;
}

.retry-btn, .cancel-btn, .download-btn {
  padding: 6px 12px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  transition: all 0.3s;
}

.retry-btn {
  background: #409eff;
  color: white;
}

.retry-btn:hover {
  background: #66b1ff;
}

.cancel-btn {
  background: #f56c6c;
  color: white;
}

.cancel-btn:hover {
  background: #f78989;
}

.download-btn {
  background: #67c23a;
  color: white;
}

.download-btn:hover {
  background: #85ce61;
}

.status-uploading {
  color: #409eff;
}

.status-success {
  color: #67c23a;
}

.status-error {
  color: #f56c6c;
}

.status-pending {
  color: #909399;
}
</style>